package cn.larry.common.utils.wx;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import cn.larry.common.utils.StringUtils;
import cn.larry.common.utils.wx.bean.WxAppConfig;
import lombok.extern.slf4j.Slf4j;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * This is created,
 * but not necessarily updated by me.
 * Therefore, AUTHOR is useless.
 * 2024/4/28 10:36
 *
 * @Version 1.0
 */
@Slf4j
public class WxAppTokenTool {

    /**
     * @param appId
     * @param secret
     * @param corpId
     * @param corpSecret
     * @return
     */
    public WxAppConfig getToken(String appId, String secret,
                                String corpId, String corpSecret) {

        if (StringUtils.isNotEmpty(appId) && StringUtils.isNotEmpty(secret)) {
            // 公众号 & 小程序
            return getWeixinToken(appId, secret);
        } else if (StringUtils.isNotEmpty(corpId) && StringUtils.isNotEmpty(corpSecret)) {
            // 企业微信应用
            return getQyWeixinToken(corpId, corpSecret);
        } else
            return null;

        //  set redis ... TODO...

    }


    /**
     * 【仅适用于微信公众号和小程序】
     * 请求微信获取token（请求微信并更新至redis中，不建议业务层直接使用）
     */
    private WxAppConfig getWeixinToken(String appId, String secret) {


        String getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                + appId
                + "&secret=" + secret;
        String body = HttpUtil.get(getUrl);
        log.info("获取微信token应答：\n{}", body);
        JSONObject respJson = JSONObject.parseObject(body);
        int expires_in = respJson.get("expires_in") != null ? (int) respJson.get("expires_in") : 0;
        Date expires_in_time = getTimeDifference(Calendar.MINUTE, expires_in / 60 - 10);
        String token = respJson.getString("access_token");

        WxAppConfig wxAppConfig = new WxAppConfig();
        // set new value
        wxAppConfig.setToken(token);
        wxAppConfig.setTokenFailureTime(expires_in_time);
        wxAppConfig.setUpdateTime(new Date());
        return wxAppConfig;
    }

    /**
     * 【企业微信应用】请求微信获取token
     *
     * @param corpId
     * @param corpSecret
     * @return
     */
    private WxAppConfig getQyWeixinToken(String corpId, String corpSecret) {

        //请求参数
        Map<String, String> uriVariables = new HashMap<>();
        uriVariables.put("corpid", corpId);
        uriVariables.put("corpsecret", corpSecret);

        WxAppConfig wxAppConfig = new WxAppConfig();

        String tokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId
                + "&corpsecret=" + corpSecret;
        String body = HttpUtil.get(tokenUrl);
        JSONObject result = JSONObject.parseObject(body);
        String token = (String) result.get("access_token");
        if (0 == ((int) result.get("errcode")) && token != null) {
            int expires_in = (int) result.get("expires_in") / 60 - 10;

            wxAppConfig.setToken(token);
            wxAppConfig.setUpdateTime(new Date());
            wxAppConfig.setTokenFailureTime(getTimeDifference(Calendar.MINUTE, expires_in));

        } else {
            throw new RuntimeException("get wechat token fail" + (String) result.get("errmsg"));
        }
        return wxAppConfig;
    }

    /**
     * 时间工具：获取当前时间相隔多久后的时间
     */
    private static Date getTimeDifference(int field, int amount) {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        date = calendar.getTime();
        return date;
    }

}
